import logging
import traceback
from django.http import HttpResponse
from rest_framework import exceptions
from rest_framework.compat import set_rollback
from rest_framework.renderers import JSONRenderer

from django.middleware.csrf import CsrfViewMiddleware
from django.contrib.auth import get_user
# from raven.contrib.django.raven_compat.models import client
from .exceptions import JsonAPIException
from rest_framework.response import Response


logger = logging.getLogger('django.request')


class JsonError(HttpResponse):
    """
    An HttpResponse that renders its content into JSON.
    """

    def __init__(self, code='OK', msg='Success', errors=[], status=400, **kwargs):
        data = {
            'code': code,
            'msg': msg,
            'errors': errors,
        }
        data.update(kwargs)
        # return Response(data)
        content = JSONRenderer().render(data)
        # print(content)
        super(JsonError, self).__init__(content, content_type='application/json', status=status)


def exception_handler(exc: JsonAPIException, context):
    try:
        return JsonError(exc.code, exc.msg, exc.errors, exc.status)
    except Exception as e:
        errors = [e.__str__(), ] + traceback.format_exc().splitlines()
        return JsonError('BAD_REQUEST', '请求错误', errors, 400)
    finally:
        pass


class CSRFCheck(CsrfViewMiddleware):
    def _reject(self, request, reason):
        """"""
        # Return the failure reason instead of an HttpResponse
        return reason


def resource_access_handler(request, resource):
    """ Callback for resource access. Determines who can see the documentation for which API. """
    # Get the underlying HttpRequest object

    # 因为rest framework使用token认证覆盖了默认的认证方式, 这里通过session来确定文档用户的真实身份

    user = get_user(request)

    # Unauthenticated, CSRF validation not required
    if not user or not user.is_active:
        return False

    reason = CSRFCheck().process_view(request, None, (), {})
    if reason:
        # CSRF failed, bail with explicit error message
        raise exceptions.PermissionDenied('CSRF Failed: %s' % reason)

    # Superusers and staff can see whatever they want
    return user.is_superuser or user.is_staff
